home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacFormat España 15
/
macformat_15.iso
/
Shareware Internet
/
Ciencia
/
CFG 2.3 (Shareware)
/
µCinema Converter
/
preferences.c
< prev
next >
Wrap
Text File
|
1994-04-02
|
13KB
|
601 lines
/********************************************************************
µCinema Converter 1.0
module: preferences.c
April 1994
by John A. Schlack
********************************************************************/
#include "constants.h"
#include "preferences.h"
#include "µCinema.h"
/* --------------------------------------------------------------------------------- */
/* preferences resource */
#define PREFS_RTYPE 'pref'
#define PREFS_ID 1000
/* STR# for preferences dialog */
#define FRAME_RATE_SET 128
#define PREFERENCES_SET 129
#define STRN_TITLE 1
#define STRN_PROMPT 2
/* preferences dialog */
#define PREFERENCES_DIALOG 129
#define FPS_POPUP_ITEM 5
#define FPS_LABEL_ITEM 4
#define PREFS_TITLE 3
#define PREFS_PROMPT 6
#define PREF_POPUP_MENU_ID 5
#define OTHER_FPS_ITEM 7
/* custom frame rate dialog */
#define FRAME_RATE_DIALOG 130
#define FRAME_EDIT_BOX 4
/* general constants */
#define DEFAULT_FPS 10
#define returnKey 13
#define enter 3
#define esc 27
#define pushButton (ctrlItem + btnCtrl)
/* --------------------------------------------------------------------------------- */
typedef struct PREFS_STRUCT
{
short framesPerSecond;
} PREFS_STRUCT;
/* --------------------------------------------------------------------------------- */
static PREFS_STRUCT rPrefs;
static short rFramesChoice;
static short rFrames;
/* --------------------------------------------------------------------------------- */
/* Private Function Prototypes */
static Boolean verifyPreferences( PREFS_STRUCT * prefs );
static pascal void updatePopupMenu( DialogPtr dialog, short item );
static void hiliteItem( Handle itemHandle, Boolean val );
static void outlineItem( DialogPtr theDialog, short theItem );
static Handle copyItemHandle( DialogPtr theDialog, short theItem );
static void invertLabel( DialogPtr dialog, short item );
static void copyItemRect( DialogPtr dialog, short item, Rect * r );
static void doPopup( DialogPtr dialog, short item, short menuID, short * choice );
static void drawTriangle( Rect * r );
static void setPopupDraw( short item, ProcPtr draw );
static pascal Boolean prefsDialogFilter( DialogPtr whichDialog, EventRecord * event,
short * itemHit );
static Boolean userFPSDialog( short * framesPerSecond );
/* --------------------------------------------------------------------------------- */
void loadPreferences( void )
{
Handle prefHand;
Boolean useDefault = true;
prefHand = (Handle) GetResource( PREFS_RTYPE, PREFS_ID );
if (prefHand != nil)
{
LoadResource( prefHand );
if (SizeResource( prefHand ) == sizeof( rPrefs ))
{
HLock( prefHand );
rPrefs = *((PREFS_STRUCT *) (*prefHand));
HUnlock( prefHand );
if (verifyPreferences( &rPrefs ))
useDefault = false;
}
ReleaseResource( prefHand );
}
if (useDefault)
rPrefs.framesPerSecond = DEFAULT_FPS;
}
/* -------------------------------------------------------------------------------- */
void savePreferences( void )
{
Handle prefHand;
PREFS_STRUCT * pp = &rPrefs;
prefHand = (Handle) GetResource( PREFS_RTYPE, PREFS_ID );
if (prefHand != nil)
{
SetHandleSize( prefHand, sizeof( PREFS_STRUCT ) );
if (MemError() == noErr)
{
HLock( prefHand );
BlockMove( (char *) pp, (char *) (*prefHand), sizeof( PREFS_STRUCT ) );
HUnlock( prefHand );
ChangedResource( prefHand );
WriteResource( prefHand );
}
ReleaseResource( prefHand );
}
else if (PtrToHand( (Ptr) pp, &prefHand, sizeof( PREFS_STRUCT ) ) == noErr)
{
AddResource( prefHand, PREFS_RTYPE, PREFS_ID, "\pPreferences" );
if (ResError() == noErr)
{
WriteResource( prefHand );
ReleaseResource( prefHand );
}
}
else
return;
}
/* --------------------------------------------------------------------------------- */
static Boolean verifyPreferences( PREFS_STRUCT * prefs )
{
if ((prefs->framesPerSecond < 1) || (prefs->framesPerSecond > 60))
return false;
return true;
}
/* --------------------------------------------------------------------------------- */
Boolean preferencesDialog( short * framesPerSecond )
{
Str255 text;
DialogPtr theDialog;
GrafPtr old;
Handle itemHandle;
short itemHit, promptSet;
Boolean dialogDone = false, error = false;
theDialog = GetNewDialog( PREFERENCES_DIALOG, nil, (WindowPtr) -1 );
if (theDialog == nil)
return false;
GetPort( &old );
SetPort( theDialog );
promptSet = (framesPerSecond != nil) ? FRAME_RATE_SET : PREFERENCES_SET;
rFrames = rPrefs.framesPerSecond;
switch( rFrames )
{
case 8: rFramesChoice = 1; break;
case 10: rFramesChoice = 2; break;
case 12: rFramesChoice = 3; break;
case 15: rFramesChoice = 4; break;
case 30: rFramesChoice = 5; break;
default: rFramesChoice = 7; break;
}
GetIndString( &(text[0]), promptSet, STRN_TITLE );
itemHandle = copyItemHandle( theDialog, PREFS_TITLE );
if (itemHandle != nil)
SetIText( itemHandle, text );
else
error = true;
if (!error)
{
GetIndString( &(text[0]), promptSet, STRN_PROMPT );
itemHandle = copyItemHandle( theDialog, PREFS_PROMPT );
if (itemHandle != nil)
SetIText( itemHandle, text );
else
error = true;
}
if (error)
{
SetPort( old );
DisposDialog( theDialog );
return false;
}
setPopupDraw( FPS_POPUP_ITEM, (ProcPtr) updatePopupMenu );
ShowWindow( theDialog );
while (!dialogDone)
{
ModalDialog( prefsDialogFilter, &itemHit );
switch( itemHit )
{
case ok:
case cancel:
dialogDone = true;
break;
case FPS_POPUP_ITEM:
invertLabel( theDialog, FPS_LABEL_ITEM );
doPopup( theDialog, FPS_POPUP_ITEM, PREF_POPUP_MENU_ID, &rFramesChoice );
invertLabel( theDialog, FPS_LABEL_ITEM );
switch( rFramesChoice )
{
case 1: rFrames = 8; break;
case 2: rFrames = 10; break;
case 3: rFrames = 12; break;
case 4: rFrames = 15; break;
case 5: rFrames = 30; break;
}
break;
}
}
SetPort( old );
DisposDialog( theDialog );
if (framesPerSecond != nil)
*framesPerSecond = rFrames;
else
{
rPrefs.framesPerSecond = rFrames;
installProgramStatus( PS_PREFS_DIRTY );
}
return (itemHit == ok);
}
/* --------------------------------------------------------------------------------- */
static pascal void updatePopupMenu( DialogPtr dialog, short item )
{
static unsigned char strAppend[] = "\p fps";
MenuHandle menu;
Str255 txt;
Rect txtR, r;
short i, j;
NumToString( (long) rFrames, &(txt[0]) );
for (i=(short) txt[0]+1, j=1; j<=(short) strAppend[0]; i++, j++)
txt[i] = strAppend[j];
txt[0] += 4;
copyItemRect( dialog, item, &r );
menu = (MenuHandle) (GetResource( 'MENU', PREF_POPUP_MENU_ID ));
if (menu != nil)
{
txtR = r;
txtR.left = txtR.left + 12;
txtR.right = txtR.right - 20;
TextBox( &txt[1], txt[0], &txtR, teJustLeft );
ReleaseResource( (Handle) menu );
}
drawTriangle( &r );
r.right = r.right - 1;
r.bottom = r.bottom - 1;
FrameRect( &r );
MoveTo( r.right, r.top + 2 );
LineTo( r.right, r.bottom );
LineTo( r.left + 2, r.bottom );
}
/* --------------------------------------------------------------------------------- */
static void hiliteItem( Handle itemHandle, Boolean val )
{
if (!val)
HiliteControl( (ControlHandle) itemHandle, 255 );
else
HiliteControl( (ControlHandle) itemHandle, 0 );
}
/* --------------------------------------------------------------------------------- */
static void outlineItem( DialogPtr theDialog, short theItem )
{
short type;
Rect box;
Handle itemHdl;
GrafPtr oldGrafPtr;
GetPort( &oldGrafPtr );
SetPort( theDialog );
GetDItem( theDialog, theItem, &type, &itemHdl, &box );
PenSize( 3, 3 );
InsetRect( &box, -4, -4 );
FrameRoundRect( &box, 16, 16 );
PenNormal();
SetPort( oldGrafPtr );
}
/* --------------------------------------------------------------------------------- */
static Handle copyItemHandle( DialogPtr theDialog, short theItem )
{
Handle item;
short itemType;
Rect box;
GetDItem( theDialog, theItem, &itemType, &item, &box );
return item;
}
/* --------------------------------------------------------------------------------- */
static void invertLabel( DialogPtr dialog, short item )
{
Rect r;
/* Correct GrafPtr is assumed set. */
copyItemRect( dialog, item, &r );
InvertRect( &r );
}
/* --------------------------------------------------------------------------------- */
static void copyItemRect( DialogPtr dialog, short item, Rect * r )
{
Handle itemHandle;
short itemType;
GetDItem( dialog, item, &itemType, &itemHandle, r );
}
/* --------------------------------------------------------------------------------- */
static void doPopup( DialogPtr dialog, short item, short menuID, short * choice )
/*
Correct GrafPtr is assumed set.
*/
{
GrafPtr old;
MenuHandle menu;
Rect r, triangle;
long result;
Point corner;
short newChoice, newFrame;
GetPort( &old );
SetPort( dialog );
copyItemRect( dialog, item, &r );
menu = GetMenu( menuID );
if (menu != NULL)
{
InsertMenu( menu, -1 );
triangle.top = r.top + 5;
triangle.left = r.right - 18;
triangle.bottom = triangle.top + 7;
triangle.right = triangle.left + 13;
EraseRect( &triangle );
corner.h = r.left;
corner.v = r.top;
LocalToGlobal( &corner );
CheckItem(menu, *choice, true);
result = PopUpMenuSelect (menu, corner.v, corner.h + 1, *choice);
CheckItem(menu, *choice, false);
DeleteMenu(menuID);
ReleaseResource( (Handle) menu );
InvalRect( &triangle );
if (HiWord (result) != 0)
{
newChoice = LoWord( result );
if (newChoice == OTHER_FPS_ITEM)
{
newFrame = rFrames;
if (userFPSDialog( &newFrame ))
{
rFrames = newFrame;
InsetRect( &r, 1, 1 );
InvalRect( &r );
*choice = newChoice;
}
}
else if (newChoice != *choice)
{
*choice = newChoice;
InsetRect( &r, 1, 1 );
InvalRect( &r );
}
}
}
SetPort( old );
}
/* --------------------------------------------------------------------------------- */
static void drawTriangle( Rect * r )
/*
Correct GrafPtr is assumed set.
*/
{
PolyHandle tri;
tri = OpenPoly ();
MoveTo( r->right - 15, r->top + 5 );
Line (5, 5);
Line (5, -5);
Line (-10, 0);
ClosePoly ();
FillPoly( tri, (ConstPatternParam) (&qd.black) );
KillPoly( tri );
}
/* --------------------------------------------------------------------------------- */
static void setPopupDraw( short item, ProcPtr draw )
{
Handle itemHandle;
Rect itemRect;
short itemType;
GetDItem (qd.thePort, item, &itemType, &itemHandle, &itemRect);
SetDItem (qd.thePort, item, itemType, (Handle) draw, &itemRect);
}
/* --------------------------------------------------------------------------------- */
static pascal Boolean prefsDialogFilter( DialogPtr whichDialog, EventRecord * event,
short * itemHit )
{
Handle itemHandle;
Rect itemRect;
long finalTicks;
short itemType, prevEdit;
Boolean filtered;
char key;
filtered = false;
switch ((*event).what)
{
case keyDown:
case autoKey:
key = (*event).message & charCodeMask;
if ((key == returnKey) || (key == enter) || (key == esc)
|| ((key == '.') && (((*event).modifiers & cmdKey) != 0)))
{
if ((key == returnKey) || (key == enter))
*itemHit = ok;
else
*itemHit = cancel;
GetDItem (whichDialog, *itemHit, &itemType, &itemHandle, &itemRect);
if ((itemType & itemDisable) == 0)
{
if ((itemType & (255 - itemDisable)) == pushButton)
{
HiliteControl ((ControlHandle) itemHandle, inButton);
Delay (8, &finalTicks);
HiliteControl ((ControlHandle) itemHandle, 0);
}
filtered = true;
}
}
break;
case updateEvt:
if ((WindowPtr) (*event).message == qd.thePort)
{
GetDItem (whichDialog, ok, &itemType, &itemHandle, &itemRect);
if ((itemType & (255 - itemDisable)) == pushButton)
outlineItem( whichDialog, ok );
}
break;
}
return filtered;
}
/* --------------------------------------------------------------------------------- */
static Boolean userFPSDialog( short * framesPerSecond )
{
Str255 text;
DialogPtr theDialog;
GrafPtr old;
Handle editTextHandle;
long fps;
short itemHit;
Boolean dialogDone = false;
theDialog = GetNewDialog( FRAME_RATE_DIALOG, nil, (WindowPtr) -1 );
if (theDialog == nil)
return false;
GetPort( &old );
SetPort( theDialog );
NumToString( (long) *framesPerSecond, text );
editTextHandle = copyItemHandle( theDialog, FRAME_EDIT_BOX );
if (editTextHandle != nil)
{
SetIText( editTextHandle, text );
SelIText( theDialog, FRAME_EDIT_BOX, 0, 32767 );
}
else
{
SetPort( old );
DisposDialog( theDialog );
return false;
}
ShowWindow( theDialog );
while (!dialogDone)
{
ModalDialog( prefsDialogFilter, &itemHit );
switch( itemHit )
{
case ok:
GetIText( editTextHandle, text );
StringToNum( text, &fps );
if ((fps < 1L) || (fps > 60L))
errorHandler( ERR_FRAME_RATE );
else
{
*framesPerSecond = (short) fps;
dialogDone = true;
}
break;
case cancel:
dialogDone = true;
break;
}
}
SetPort( old );
DisposDialog( theDialog );
return (itemHit == ok);
}
/* --------------------------------------------------------------------------------- */
short copyPrefsFPS( void )
{
return rPrefs.framesPerSecond;
}